package com.gitee.wsl.common.chart.sample

import android.graphics.Canvas
import android.graphics.Paint
import android.graphics.PointF
import android.graphics.RectF
import com.gitee.wsl.android.ext.math.calcArcEndPointXY
import com.gitee.wsl.common.chart.ChartEnum
import com.gitee.wsl.common.chart.listener.click.ArcPosition
import com.gitee.wsl.common.chart.listener.click.BarPosition
import com.gitee.wsl.common.chart.listener.click.PlotArcPosition
import com.gitee.wsl.common.chart.listener.click.PlotBarPosition
import com.gitee.wsl.common.chart.listener.click.PlotPointPosition
import com.gitee.wsl.common.chart.listener.click.PointPosition
import com.gitee.wsl.common.chart.listener.click.PositionRecord
import com.gitee.wsl.common.draw.area.Viewport
import com.gitee.wsl.common.chart.render.foreground.info.ToolTip
import com.gitee.wsl.android.ui.ext.type.drawPercentArc
import com.gitee.wsl.math.Math
import com.gitee.wsl.jvm.math.add
import com.gitee.wsl.jvm.math.div

import timber.log.Timber


class ChartSelectHelper(val chart:XChart) {

     var isSelectClickAble = false

     var clickRangeExtValue = 0

     var recordset = mutableListOf<PositionRecord>()

     var selectID = -1
     var selectDataID = -1
     var selectDataChildID = -1

     var isShowClickedFocus = false

     var focusPaint: Paint = Paint(Paint.ANTI_ALIAS_FLAG)

     var focusPoint: PointF? = null
     var focusRadius = 0.0f
     var focusRect: RectF? = null

    // private Path mFocusPath = null;
     var focusArcPosition: ArcPosition? = null
     var isFocusArcSelect = false

     var toolTip: ToolTip = ToolTip()

    /**
     * 激活点击事件
     */
    fun ActiveListenItemClick() {
        isSelectClickAble = true
    }

    /**
     * 禁用点击事件
     */
    fun DeactiveListenItemClick() {
        isSelectClickAble = false
    }

    /**
     * 返回事件处理状态
     *
     * @return 是否激活
     */
    fun getListenItemClickStatus(): Boolean {
        return isSelectClickAble
    }

    /**
     * 返回记录集
     *
     * @return 记录集
     */
    fun getPositionRecordset(): List<PositionRecord> {
        return recordset
    }

    /**
     * 是点对点击选中对象显示相关焦点标识
     */
    fun showClikedFocus() {
        isShowClickedFocus = true
    }

    private fun clearSelected() {
        selectID = -1
        selectDataID = -1
        selectDataChildID = -1
    }

    private fun saveSelected(recordID: Int, dataID: Int, dataChildID: Int) {
        selectID = recordID
        selectDataID = dataID
        selectDataChildID = dataChildID
    }

    protected fun getSelected(): Int {
        return selectID
    }

     /*fun savePointRecord(
        dataID: Int, childID: Int,
        x: Float, y: Float, r: RectF
    ) {
        if (!getListenItemClickStatus()) return
        savePointRecord(dataID, childID, x, y, r.left, r.top, r.right, r.bottom)
    }

     fun savePointRecord(
        dataID: Int, childID: Int,
        x: Float, y: Float, left: Float, top: Float, right: Float, bottom: Float
    ) {
        if (!getListenItemClickStatus()) return

        val pRecord = PlotPointPosition()
        pRecord.savePlotDataID(dataID)
        pRecord.savePlotDataChildID(childID)
        pRecord.savePlotPosition(x, y)
        pRecord.savePlotRectF(left, top, right, bottom)
        pRecord.extPointClickRange(clickRangeExtValue)
        recordset.add(pRecord)
    }

     fun saveBarRectFRecord(
        dataID: Int, childID: Int, left: Float,
        top: Float, right: Float, bottom: Float
    ) {
        if (!getListenItemClickStatus()) return

        val pRecord = PlotBarPosition()
        pRecord.savePlotDataID(dataID)
        pRecord.savePlotDataChildID(childID)
        pRecord.savePlotRectF(left, top, right, bottom)
        pRecord.extPointClickRange(clickRangeExtValue)
        recordset.add(pRecord)
    }

     fun saveBarRecord(
        dataID: Int, childID: Int, x: Float, y: Float,
        r: RectF?
    ) {
        if (!getListenItemClickStatus()) return
        val pRecord = PlotBarPosition()
        pRecord.savePlotDataID(dataID)
        pRecord.savePlotDataChildID(childID)
        pRecord.savePlotRectF(r)
        pRecord.extPointClickRange(clickRangeExtValue)
        recordset.add(pRecord)
    }

    // 保存角度 (半径)
     fun saveArcRecord(
        dataID: Int, centerX: Float, centerY: Float,
        radius: Float, offsetAngle: Float, Angle: Float, selectedOffset: Float,
        initialAngle: Float
    ) {
        if (!getListenItemClickStatus()) return
        val pRecord = PlotArcPosition()
        pRecord.savePlotDataID(dataID)
        pRecord.savePlotCirXY(centerX, centerY)
        pRecord.saveAngle(radius, offsetAngle, Angle, selectedOffset)
        pRecord.saveInitialAngle(initialAngle)
        recordset.add(pRecord)
    }*/

    /**
     * 为了让触发更灵敏，可以扩大指定px的点击监听范围
     *
     * @param value
     * 扩大多少点击监听范围
     */
    fun extPointClickRange(value: Int) {
        clickRangeExtValue = value
    }

    /**
     * 检查是否点击在处理范围内
     *
     * @param x
     * 当前点击点X坐标
     * @param y
     * 当前点击点Y坐标
     * @return 是否需处理
     */
    fun isPlotClickArea(x: Float, y: Float): Boolean {
        if (!getListenItemClickStatus()) return false
        if (x.compareTo(getPlotArea().left) == -1) return false
        if (x.compareTo(getPlotArea().right) == 1) return false
        if (y.compareTo(getPlotArea().top) == -1) return false
        return y.compareTo(getPlotArea().bottom) != 1
    }

    private fun getPlotArea(): Viewport {
      return chart.plotViewport
    }

    /**
     * 返回对应的记录
     *
     * @param x
     * 当前点击点X坐标
     * @param y
     * 当前点击点Y坐标
     * @return 记录类
     */
     fun getArcRecord(x: Float, y: Float): ArcPosition? {
        if (!getListenItemClickStatus()) return null
        if (!isPlotClickArea(x, y)) return null
        if (!getClikedScaleStatus()) return null
        val it: Iterator<*> = recordset.iterator()
        while (it.hasNext()) {
            val record = it.next() as PlotArcPosition
            if (record.compareF(x, y)) {
                saveSelected(
                    record.recordID, record.dataID,
                    record.dataChildID
                )
                return record
            }
        }
        clearSelected()
        return null
    }

     fun getBarRecord(x: Float, y: Float): BarPosition? {
        if (!getListenItemClickStatus()) return null
        if (!isPlotClickArea(x, y)) return null
        if (!getClikedScaleStatus()) return null
        val it: Iterator<*> = recordset.iterator()
        while (it.hasNext()) {
            val record = it.next() as PlotBarPosition
            if (record.compareF(x, y)) {
                saveSelected(
                    record.recordID, record.dataID,
                    record.dataChildID
                )
                return record
            }
        }
        clearSelected()
        return null
    }

     fun getPointRecord(x: Float, y: Float): PointPosition? {
        if (!getListenItemClickStatus()) return null
        if (!isPlotClickArea(x, y)) return null
        if (!getClikedScaleStatus()) return null
        val it: Iterator<*> = recordset.iterator()
        while (it.hasNext()) {
            val record = it.next() as PlotPointPosition
            if (record.compareF(x, y)) {
                saveSelected(
                    record.recordID, record.dataID,
                    record.dataChildID
                )
                return record
            }
        }
        clearSelected()
        return null
    }

    private fun getClikedScaleStatus(): Boolean {
        return false
        //return chart.getClikedScaleStatus()
    }

    /*protected fun initPositionRecord() {
        recordset.clear()
    }*/


    /**
     * 点的焦点参数
     *
     * @param point
     * 点
     * @param radius
     * 半径
     */
    fun showFocusPointF(point: PointF, radius: Float) {
        focusPoint = point
        focusRadius = radius
    }

    /**
     * 柱形类的焦点参数
     *
     * @param rect
     * 柱形
     */
    fun showFocusRectF(rect: RectF) {
        focusRect = rect
    }

    /**
     * 图，扇形类的焦点参数
     *
     * @param arc
     * 扇形选中类
     */

    fun showFocusArc(arc: ArcPosition, selected: Boolean=false) {
        focusArcPosition = arc
        isFocusArcSelect = selected
    }

    /**
     * 开放提示信息类
     *
     * @return 信息基类
     */


    /**
     * 绘制提示信息
     *
     * @param canvas
     * 画布
     */
     fun renderToolTip(canvas: Canvas) {
        toolTip.renderInfo(canvas)
    }

     fun drawFocusRect(
        canvas: Canvas, dataID: Int, childID: Int,
        left: Float, top: Float, right: Float, bottom: Float
    ): Boolean {
        if (!isShowClickedFocus) return true
        if (-1 == selectID) return false
        if (null == focusRect) return false

        // if(null == mFocusPath) mFocusPath = new Path();
        if (selectDataID == dataID && selectDataChildID == childID) {
            focusRect!!.left = left
            focusRect!!.top = top
            focusRect!!.right = right
            focusRect!!.bottom = bottom
            canvas.drawRect(focusRect!!,focusPaint)
            focusRect!!.setEmpty()

            /*
			 * mFocusPath.moveTo(left, bottom); mFocusPath.lineTo(left, top);
			 * mFocusPath.lineTo(right, top); mFocusPath.lineTo(right, bottom);
			 * mFocusPath.close(); canvas.drawPath(mFocusPath, getFocusPaint());
			 * mFocusPath.reset();
			 */
            clearSelected()
        }
        return true
    }

    /**
     * 绘制焦点形状
     *
     * @param canvas
     * 画布
     * @return 是否绘制成功
     */
    fun renderFocusShape(canvas: Canvas): Boolean {
        if (!isShowClickedFocus) return true
        val ctype: ChartEnum.ChartType = chart.getType()
        if (ChartEnum.ChartType.BAR == ctype || ChartEnum.ChartType.BAR3D == ctype || ChartEnum.ChartType.STACKBAR == ctype) {
            return true
        }
        try {
            if (null != focusPoint) {
                canvas.drawCircle(
                    focusPoint!!.x, focusPoint!!.y, focusRadius,
                    focusPaint
                )
                focusPoint = null
                focusRadius = 0.0f
            } else if (null != focusRect) {
                /*
				 * canvas.save();
				 * canvas.clipRect(plotArea.getLeft(),plotArea.getTop(),
				 * plotArea.getRight(),plotArea.getBottom());
				 * canvas.drawRect(mFocusRect, getFocusPaint());
				 * canvas.restore(); mFocusRect = null;
				 */
            } else if (null != focusArcPosition) {
                val pointCir = focusArcPosition!!.pointF
                var cirX = pointCir!!.x
                var cirY = pointCir.y
                val radius = focusArcPosition!!.radius
                if (isFocusArcSelect) {
                    // 偏移圆心点位置(默认偏移半径的1/10)
                    val newRadius: Float = Math.div(
                        radius,
                        focusArcPosition!!.selectedOffset
                    )
                    // 计算百分比标签
                    val point = Math.calcArcEndPointXY(
                        cirX,
                        cirY,
                        newRadius,
                        Math.add(
                            focusArcPosition!!.startAngle,
                            focusArcPosition!!.sweepAngle / 2f
                        )
                    )
                    cirX = point.x
                    cirY = point.y
                }
                canvas.drawPercentArc(
                    focusPaint,
                    cirX, cirY, radius, focusArcPosition!!.startAngle,
                    focusArcPosition!!.sweepAngle, true
                )
                focusArcPosition = null
            } else {
                return false
            }
        } catch (ex: Exception) {
            Timber.d( ex.toString())
        }
        return true
    }


    /*fun render(canvas: Canvas): Boolean {
        // 绘制图表

       // 清理
       initPositionRecord()

        return true
    }*/

}